﻿using System;
using System.Collections.Generic;
using System.Linq;

using Biz.EF.Platform.Gxt;

using Hjt212Parser;
using log4net;

namespace Biz.Process
{
    /// <summary>
    /// 主要处理统计，日数据统计到月数据，月数据统计到年
    /// </summary>
    public static class ProcessorSummation4Total
    {
        private static ILog Log = LogManager.GetLogger(typeof(ProcessorSummation4Total));
        /// <summary>
        /// 根据2061（小时数据）指令触发日数据累加(总量)
        /// </summary>
        /// <param name="pCtx"></param>
        /// <param name="content"></param>
        public static void Process2061Sum2Day(PlatformGxtContext pCtx, string content)
        {
            try
            {
                var mnMonitor = Parser.GetStringByKey("MN", content);
                if (string.IsNullOrEmpty(mnMonitor)) return;
                var mn = MonitorAndTotalMnMap.GetTotalMnByMonitorMn(mnMonitor);
                if (string.IsNullOrEmpty(mn)) return;
                var datatime = Parser.GetDateTimeByKey("DataTime", content);
                if (!datatime.HasValue) return;
                var now = DateTime.Now;
                if(datatime.Value.Day!=now.Day) return;
                //if (!(datatime.Value.Hour == 9 || datatime.Value.Hour == 14 || datatime.Value.Hour == 17)) return;
                if (datatime.Value.Hour < 8 || datatime.Value.Hour > 18) return;
                //1、插入或更新主记录
                var begin = new DateTime(datatime.Value.Year, datatime.Value.Month, datatime.Value.Day, 0, 0, 0);
                var end = begin.AddDays(1);
                var xaxis = pCtx.xaxis_day.Where(t => t.MN.Equals(mn))
                    .FirstOrDefault(t => t.datatime >= begin && t.datatime < end);
                if (xaxis == null)
                {
                    xaxis = new xaxis_day();
                    pCtx.xaxis_day.Add(xaxis);
                }
                xaxis.MN = mn;
                xaxis.datatime = datatime.Value;
                pCtx.SaveChanges();
                //2、插入或更新状态
                var state = pCtx.state_day.FirstOrDefault(t => t.MN.Equals(mn));
                if (state != null)
                {
                    pCtx.state_day.Remove(state);
                    pCtx.SaveChanges();
                }
                state = new state_day();
                state.MN = mn;
                state.datatime = datatime.Value;
                state.id = xaxis.id;
                pCtx.state_day.Add(state);
                pCtx.SaveChanges();
                //3、插入或更新数据
                var xaxises =
                     pCtx.xaxis_hour.Where(t => t.MN.Equals(mnMonitor))
                         .Where(t => t.datatime >= begin && t.datatime < end)
                         .ToList();
                List<int> dayIds = xaxises.Select(t => t.id).ToList();
                if (dayIds.Count != 0)
                {
                    var factors = Parser.GetPollutantCodes(content);
                    foreach (var factor1 in factors)
                    {
                        var factor = factor1;
                        var oldFactor = Convert.GetOldFactorFromNewFactor(factor);
                        if (oldFactor != null)
                        {
                            factor = oldFactor;
                        }
                        var avg = pCtx.data_hour.Where(t => dayIds.Contains(t.ID)).Where(t => t.pollutant.Equals(factor)).Average(t => t.avg);
                        var cou = pCtx.data_hour.Where(t => dayIds.Contains(t.ID)).Where(t => t.pollutant.Equals(factor)).Sum(t => t.cou);
                        var min = pCtx.data_hour.Where(t => dayIds.Contains(t.ID)).Where(t => t.pollutant.Equals(factor)).Min(t => t.min);
                        var max = pCtx.data_hour.Where(t => dayIds.Contains(t.ID)).Where(t => t.pollutant.Equals(factor)).Max(t => t.max);

                        if (avg != null && cou != null && min != null && max != null)
                        {
                            data_day data =
                                pCtx.data_day.Where(t => t.ID == xaxis.id).FirstOrDefault(t => t.pollutant.Equals(factor));
                            if (data == null)
                            {
                                data = new data_day();
                                pCtx.data_day.Add(data);
                            }
                            data.ID = xaxis.id;
                            data.pollutant = factor;
                            data.avg = avg.Value;
                            data.cou = cou.Value;
                            data.min = min.Value;
                            data.max = max.Value;
                          
                        }
                    }
                }
                pCtx.SaveChanges();
            }
            catch (Exception ex)
            {
                Log.Error( ex);
            }

        }
        /// <summary>
        /// 根据2061（小时数据）指令触发月排放和年排放数据计算(总量)
        /// </summary>
        /// <param name="pCtx"></param>
        /// <param name="content"></param>
        public static void Process2061Sum2TotalEmission(PlatformGxtContext pCtx, string content)
        {
            var mn = Parser.GetStringByKey("MN", content);
            if (string.IsNullOrEmpty(mn)) return;
            var totalMn = MonitorAndTotalMnMap.GetTotalMnByMonitorMn(mn);
            if (string.IsNullOrEmpty(totalMn)) return;
            //TODO:如果有阻塞就放在上班时间统计（如9点到17点）
            var datatime = Parser.GetDateTimeByKey("DataTime", content);
            if (datatime == null) return;

            var now = DateTime.Now;
            if (datatime.Value.Day != now.Day) return;
            //if (!(datatime.Value.Hour==8||datatime.Value.Hour==14 || datatime.Value.Hour ==17)) return;
            if (datatime.Value.Hour< 8 ||  datatime.Value.Hour> 18) return;
            var company = InfoBuffer.GetCompanyByMn(totalMn, MnType.Total);
            if (company == null)
            {
                Log.Info("没有对应的企业，总量MN:"+ totalMn+" 在线MN:"+mn);
                return;
            }
            var factors = Parser.GetPollutantCodes(content);
            foreach (var factor1 in factors)
            {
                var factor = factor1;
                var oldFactor = Convert.GetOldFactorFromNewFactor(factor);
                if (oldFactor != null)
                {
                    factor = oldFactor;
                }
                //实时记录表中每个企业每个因子应该只有一条记录，多余就删除
                var realdatas = pCtx.total_realtime_data
                     .Where(t => t.ps_id_ == company.PsID)
                     .Where(t => t.pollutant_type_.Equals(factor)).ToList();
                if (realdatas.Count > 1)
                {
                    pCtx.total_realtime_data.RemoveRange(realdatas);
                    pCtx.SaveChanges();
                }
                var realdata = pCtx.total_realtime_data.Where(t => t.ps_id_ == company.PsID)
                    .FirstOrDefault(t => t.pollutant_type_.Equals(factor));
                if (realdata == null)
                {
                    realdata = new total_realtime_data();
                    pCtx.total_realtime_data.Add(realdata);
                }


                var month = new DateTime(datatime.Value.Year, datatime.Value.Month, 1);
                var nextMonth = month.AddMonths(1);
                var year = new DateTime(datatime.Value.Year, 1, 1);
                var nextYear = year.AddYears(1);
                var monthdatas = pCtx.total_month_data
                     .Where(t => t.ps_id_ == company.PsID)
                     .Where(t => t.pollutant_type_.Equals(factor))
                     .Where(t => t.data_time_ >= month && t.data_time_ < nextMonth)
                     .ToList();
                if (monthdatas.Count > 1)
                {
                    pCtx.total_month_data.RemoveRange(monthdatas);
                    pCtx.SaveChanges();
                }
                var monthdata = pCtx.total_month_data.Where(t => t.ps_id_ == company.PsID)
                    .FirstOrDefault(t => t.pollutant_type_.Equals(factor));
                if (monthdata == null)
                {
                    monthdata = new total_month_data();
                    pCtx.total_month_data.Add(monthdata);
                }

                var vMonthData = pCtx.v_data_month.Where(t => t.pollutant.Equals(factor))
                    .Where(t => t.MN.Equals(totalMn)).FirstOrDefault(t => t.datatime > month && t.datatime < nextMonth);
                var vYearData = pCtx.v_data_year.Where(t => t.pollutant.Equals(factor))
                    .Where(t => t.MN.Equals(totalMn)).FirstOrDefault(t => t.datatime > year && t.datatime < nextYear);
                var vEmissionPlan =
                    pCtx.v_emission_plan.Where(t => t.pollutant_code_.Equals(factor))
                        .FirstOrDefault(t => t.code_.Equals(totalMn));


                monthdata.data_time_ = datatime;
                monthdata.ps_id_ = company.PsID;
                monthdata.pollutant_type_ = factor;
                
                monthdata.pollution_source_alias_ = company.Alias;
                monthdata.month_pi_amount_ = (vMonthData != null && vMonthData.cou != null) ? vMonthData.cou : 0;
                monthdata.year_pi_amount_ = (vYearData != null && vYearData.cou != null) ? vYearData.cou : 0;
                monthdata.year_allow_amount_ = (vEmissionPlan?.year_allow_ != null) ? (float)vEmissionPlan.year_allow_.Value : 1;
                monthdata.year_remain_amount_ = monthdata.year_allow_amount_.Value - monthdata.year_pi_amount_.Value;
                monthdata.year_percent_ = (Math.Abs(monthdata.year_allow_amount_.Value) > 0.1) ? monthdata.year_pi_amount_.Value * 100 / monthdata.year_allow_amount_.Value : 100;

                realdata.data_time_ = datatime;
                realdata.ps_id_ = company.PsID;
                realdata.pollutant_type_ = factor;
               
                realdata.pollution_source_alias_ = company.Alias;
                realdata.month_pi_amount_ = (vMonthData != null&&vMonthData.cou!=null) ? vMonthData.cou : 0;
                realdata.month_allow_amount_ = (monthdata.year_remain_amount_.Value + monthdata.month_pi_amount_.Value) /
                                               (13 - datatime.Value.Month);

                realdata.month_remain_amount_ = realdata.month_allow_amount_ - realdata.month_pi_amount_;
                realdata.month_percent_ = (Math.Abs(realdata.month_allow_amount_.Value) > 0.1) ? realdata.month_pi_amount_.Value * 100 / realdata.month_allow_amount_.Value : 100;

                pCtx.SaveChanges();

            }

        }
        /// <summary>
        /// 根据2031（日数据）指令触发月数据累加(总量)
        /// </summary>
        /// <param name="pCtx"></param>
        /// <param name="content"></param>
        public static void Process2031Sum2Month(PlatformGxtContext pCtx, string content)
        {
            try
            {
                var mnMonitor = Parser.GetStringByKey("MN", content);
                if (string.IsNullOrEmpty(mnMonitor)) return;
                var mn = MonitorAndTotalMnMap.GetTotalMnByMonitorMn(mnMonitor);
                if (string.IsNullOrEmpty(mn)) return;
                var datatime = Parser.GetDateTimeByKey("DataTime", content);
                if (!datatime.HasValue) return;
                //1、插入或更新主记录
                var begin = new DateTime(datatime.Value.Year, datatime.Value.Month, 1, 0, 0, 0);
                var end = begin.AddMonths(1);
                var xaxis = pCtx.xaxis_month.Where(t => t.MN.Equals(mn))
                    .FirstOrDefault(t => t.datatime >= begin && t.datatime < end);
                if (xaxis == null)
                {
                    xaxis = new xaxis_month();
                    pCtx.xaxis_month.Add(xaxis);
                }
                xaxis.MN = mn;
                xaxis.datatime = datatime;
                pCtx.SaveChanges();
                //2、插入或更新状态
                var state = pCtx.state_month.FirstOrDefault(t => t.MN.Equals(mn));
                if (state == null)
                {
                    state = new state_month();
                    pCtx.state_month.Add(state);
                }
                state.MN = mn;
                state.datatime = datatime.Value;
                state.id = xaxis.id;
                pCtx.SaveChanges();
                //3、插入或更新数据
                var xaxises =
                    pCtx.xaxis_day.Where(t => t.MN.Equals(mnMonitor))
                        .Where(t => t.datatime >= begin && t.datatime < end)
                        .ToList();
                List<int> dayIds = xaxises.Select(xaxisDay => xaxisDay.id).ToList();
                if (dayIds.Count != 0)
                {
                    var factors = Parser.GetPollutantCodes(content);
                    foreach (var factor1 in factors)
                    {
                        var factor = factor1;
                        var oldFactor = Convert.GetOldFactorFromNewFactor(factor);
                        if (oldFactor != null)
                        {
                            factor = oldFactor;
                        }
                        var avg = pCtx.data_day.Where(t => dayIds.Contains(t.ID)).Where(t => t.pollutant.Equals(factor)).Average(t => t.avg);
                        var cou = pCtx.data_day.Where(t => dayIds.Contains(t.ID)).Where(t => t.pollutant.Equals(factor)).Sum(t => t.cou);
                        var min = pCtx.data_day.Where(t => dayIds.Contains(t.ID)).Where(t => t.pollutant.Equals(factor)).Min(t => t.min);
                        var max = pCtx.data_day.Where(t => dayIds.Contains(t.ID)).Where(t => t.pollutant.Equals(factor)).Max(t => t.max);

                        if (avg != null && cou != null && min != null && max != null)
                        {
                            data_month data =
                                pCtx.data_month.Where(t => t.ID == xaxis.id).FirstOrDefault(t => t.pollutant.Equals(factor));
                            if (data == null)
                            {
                                data = new data_month();
                                pCtx.data_month.Add(data);
                            }
                            data.ID = xaxis.id;
                            data.pollutant = factor;
                            data.avg = avg.Value;
                            data.cou = cou.Value;
                            data.min = min.Value;
                            data.max = max.Value;
                        }
                    }
                }
                pCtx.SaveChanges();
            }
            catch (Exception ex)
            {
                Log.Error( ex);
            }

        }
        /// <summary>
        /// 根据2031（日数据）指令触发年数据累加(总量)
        /// </summary>
        /// <param name="pCtx"></param>
        /// <param name="content"></param>
        public static void Process2031Sum2Year(PlatformGxtContext pCtx, string content)
        {
            try
            {
                var mnMonitor = Parser.GetStringByKey("MN", content);
                if (string.IsNullOrEmpty(mnMonitor)) return;
                var mn = MonitorAndTotalMnMap.GetTotalMnByMonitorMn(mnMonitor);
                if (string.IsNullOrEmpty(mn)) return;
                var datatime = Parser.GetDateTimeByKey("DataTime", content);
                if (!datatime.HasValue) return;
                //1、插入或更新主记录
                var begin = new DateTime(datatime.Value.Year, 1, 1, 0, 0, 0);
                var end = begin.AddYears(1);
                var xaxis = pCtx.xaxis_year.Where(t => t.MN.Equals(mn))
                    .FirstOrDefault(t => t.datatime >= begin && t.datatime < end);
                if (xaxis == null)
                {
                    xaxis = new xaxis_year();
                    pCtx.xaxis_year.Add(xaxis);
                }
                xaxis.MN = mn;
                xaxis.datatime = datatime;
                pCtx.SaveChanges();
                //2、插入或更新状态

                var state = pCtx.state_year.FirstOrDefault(t => t.MN.Equals(mn));
                if (state == null)
                {
                    state = new state_year();
                    pCtx.state_year.Add(state);
                }
                state.MN = mn;
                state.datatime = datatime.Value;
                state.id = xaxis.id;
                pCtx.SaveChanges();
                //3、插入或更新数据
                var xaxises =
                    pCtx.xaxis_day.Where(t => t.MN.Equals(mnMonitor))
                        .Where(t => t.datatime >= begin && t.datatime < end)
                        .ToList();
                List<int> dayIds = xaxises.Select(xaxisDay => xaxisDay.id).ToList();
                if (dayIds.Count != 0)
                {
                    var factors = Parser.GetPollutantCodes(content);
                    foreach (var factor1 in factors)
                    {
                        var factor = factor1;
                        var oldFactor = Convert.GetOldFactorFromNewFactor(factor);
                        if (oldFactor != null)
                        {
                            factor = oldFactor;
                        }
                        var avg = pCtx.data_day.Where(t => dayIds.Contains(t.ID)).Where(t => t.pollutant.Equals(factor)).Average(t => t.avg);
                        var cou = pCtx.data_day.Where(t => dayIds.Contains(t.ID)).Where(t => t.pollutant.Equals(factor)).Sum(t => t.cou);
                        var min = pCtx.data_day.Where(t => dayIds.Contains(t.ID)).Where(t => t.pollutant.Equals(factor)).Min(t => t.min);
                        var max = pCtx.data_day.Where(t => dayIds.Contains(t.ID)).Where(t => t.pollutant.Equals(factor)).Max(t => t.max);

                        if (avg != null && cou != null && min != null && max != null)
                        {
                            data_year data =
                                pCtx.data_year.Where(t => t.ID == xaxis.id).FirstOrDefault(t => t.pollutant.Equals(factor));
                            if (data == null)
                            {
                                data = new data_year();
                                pCtx.data_year.Add(data);
                            }
                            data.ID = xaxis.id;
                            data.pollutant = factor;
                            data.avg = avg.Value;
                            data.cou = cou.Value;
                            data.min = min.Value;
                            data.max = max.Value;
                        }
                    }
                }
                pCtx.SaveChanges();
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }

        }
    }
}
